namespace SubhadraSolutions.Sharp.Logging.Parsing
{
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;

    #region Delegates

    public delegate LogRecord LogRecordParserDelegate(StreamReader reader);

    #endregion Delegates

    public class LogFileEnumerable : IEnumerable<LogRecord>
    {
        #region Fields

        private readonly string _fileName;
        private readonly LogRecordParserDelegate _parserDelegate;

        #endregion Fields

        #region Constructors

        public LogFileEnumerable(string fileName, LogRecordParserDelegate parserDelegate)
        {
            _fileName = fileName;
            _parserDelegate = parserDelegate;
        }

        #endregion Constructors

        #region Methods

        public IEnumerator<LogRecord> GetEnumerator()
        {
            return new LogFileEnumerator(_fileName, _parserDelegate);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new LogFileEnumerator(_fileName, _parserDelegate);
        }

        #endregion Methods

        #region Nested Types

        private sealed class LogFileEnumerator : IEnumerator<LogRecord>
        {
            #region Fields

            private readonly string _fileName;
            private readonly LogRecordParserDelegate _parserDelegate;

            private StreamReader _reader;

            #endregion Fields

            #region Constructors

            public LogFileEnumerator(string fileName, LogRecordParserDelegate parserDelegate)
            {
                _fileName = fileName;
                _parserDelegate = parserDelegate;
                Reset();
            }

            #endregion Constructors

            #region Properties

            public LogRecord Current
            {
                get;
                private set;
            }

            object IEnumerator.Current
            {
                get { return Current; }
            }

            #endregion Properties

            #region Methods

            public void Dispose()
            {
                _reader.Close();
            }

            public bool MoveNext()
            {
                Current = _parserDelegate(_reader);
                return Current != null;
            }

            public void Reset()
            {
                _reader = new StreamReader(_fileName, Encoding.ASCII);
            }

            #endregion Methods
        }

        #endregion Nested Types
    }
}